using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using VotingSystem.Data;
using VotingSystem.Models;
using VotingSystem.ViewModels;
using System.Security.Claims;
using System.Linq;
using System.Collections.Generic;
using Microsoft.AspNetCore.Identity;
using VotingSystem.Services;

namespace VotingSystem.Controllers
{
    [Authorize]
    public class SurveysController : Controller
    {
        private readonly ApplicationDbContext _context;
        private readonly ILogger<SurveysController> _logger;
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly PdfExportService _pdfExportService;
        private readonly ExcelExportService _excelExportService;

        public SurveysController(ApplicationDbContext context, ILogger<SurveysController> logger, UserManager<ApplicationUser> userManager, PdfExportService pdfExportService, ExcelExportService excelExportService)
        {
            _context = context;
            _logger = logger;
            _userManager = userManager;
            _pdfExportService = pdfExportService;
            _excelExportService = excelExportService;
        }

        // GET: Surveys
        public async Task<IActionResult> Index(string filter = "all")
        {
            try
            {
                _logger.LogInformation("正在获取问卷列表，筛选条件：{Filter}", filter);
                var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
                var query = _context.Surveys
                    .Include(s => s.Creator)
                    .Where(s => s.IsPublic || s.CreatorId == userId);

                switch (filter)
                {
                    case "active":
                        query = query.Where(s => s.IsActive && (!s.EndTime.HasValue || s.EndTime.Value > DateTime.Now));
                        break;
                    case "ended":
                        query = query.Where(s => !s.IsActive || (s.EndTime.HasValue && s.EndTime.Value <= DateTime.Now));
                        break;
                    case "my":
                        query = query.Where(s => s.CreatorId == userId);
                        break;
                }

                var surveys = await query
                    .OrderByDescending(s => s.CreatedAt)
                    .ToListAsync();

                ViewBag.CurrentFilter = filter;
                _logger.LogInformation("成功获取问卷列表，共 {Count} 条记录", surveys.Count);
                return View(surveys);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取问卷列表时发生错误");
                TempData["ErrorMessage"] = "获取问卷列表时发生错误：" + ex.Message;
                return View(new List<Survey>());
            }
        }

        // GET: Surveys/MySurveys
        public async Task<IActionResult> MySurveys(string filter = "all")
        {
            var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
            if (string.IsNullOrEmpty(userId))
            {
                return RedirectToAction("Login", "Account");
            }

            var query = _context.Surveys
                .Include(s => s.Questions)
                    .ThenInclude(q => q.Options)
                .Include(s => s.Responses)
                .Where(s => s.CreatorId == userId);

            // 应用筛选
            switch (filter)
            {
                case "active":
                    query = query.Where(s => s.IsActive && (!s.EndTime.HasValue || s.EndTime.Value > DateTime.Now));
                    break;
                case "ended":
                    query = query.Where(s => !s.IsActive || (s.EndTime.HasValue && s.EndTime.Value <= DateTime.Now));
                    break;
                default: // "all"
                    // 不需要额外筛选
                    break;
            }

            var surveys = await query
                .OrderByDescending(s => s.CreatedAt)
                .ToListAsync();

            ViewBag.CurrentFilter = filter;

            var viewModel = new SurveyListViewModel
            {
                Surveys = surveys
            };

            return View(viewModel);
        }

        // GET: Surveys/Details/5
        public async Task<IActionResult> Details(int? id, string? token = null, bool showResponses = false)
        {
            if (id == null)
            {
                return NotFound();
            }

            var survey = await _context.Surveys
                .Include(s => s.Creator)
                .Include(s => s.Questions)
                    .ThenInclude(q => q.Options)
                .FirstOrDefaultAsync(s => s.Id == id);

            if (survey == null)
            {
                return NotFound();
            }

            // 检查访问权限
            var currentUser = await _userManager.GetUserAsync(User);
            var isCreator = currentUser != null && survey.CreatorId == currentUser.Id;

            // 如果是创建者访问，重定向到带token的URL
            if (isCreator && string.IsNullOrEmpty(token))
            {
                return RedirectToAction(nameof(Details), new { id = survey.Id, token = survey.AccessToken });
            }

            // 检查访问权限
            if (!isCreator && string.IsNullOrEmpty(token))
            {
                return RedirectToAction("AccessDenied", "Home");
            }

            if (!isCreator && token != survey.AccessToken)
            {
                return RedirectToAction("AccessDenied", "Home");
            }

            // 如果不是创建者，重定向到填写页面
            if (!isCreator)
            {
                return RedirectToAction(nameof(Fill), new { id = survey.Id });
            }

            // 获取问卷的响应数据
            var responses = await _context.SurveyResponses
                .Include(r => r.QuestionResponses)
                    .ThenInclude(qr => qr.SelectedOptions)
                .Where(r => r.SurveyId == id)
                .ToListAsync();

            // 计算统计数据
            var statistics = new Dictionary<int, Dictionary<int, int>>();
            foreach (var question in survey.Questions)
            {
                statistics[question.Id] = new Dictionary<int, int>();
                foreach (var option in question.Options)
                {
                    var count = responses
                        .SelectMany(r => r.QuestionResponses)
                        .Where(qr => qr.QuestionId == question.Id)
                        .SelectMany(qr => qr.SelectedOptions)
                        .Count(o => o.OptionId == option.Id);
                    statistics[question.Id][option.Id] = count;
                }
            }

            ViewData["ShowResponses"] = showResponses;
            ViewData["Statistics"] = statistics;
            ViewData["TotalResponses"] = responses.Count;

            return View(survey);
        }

        // GET: Surveys/Create
        public IActionResult Create()
        {
            var viewModel = new SurveyCreateViewModel();
            return View(viewModel);
        }

        // POST: Surveys/Create
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create(SurveyCreateViewModel viewModel)
        {
            if (ModelState.IsValid)
            {
                var survey = new Survey
                {
                    Title = viewModel.Title,
                    Description = viewModel.Description,
                    IsPublic = viewModel.IsPublic,
                    IsAnonymous = viewModel.IsAnonymous,
                    CreatorId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value,
                    CreatedAt = DateTime.Now,
                    AccessToken = Guid.NewGuid().ToString("N"),
                    Questions = viewModel.Questions.Select(q => new SurveyQuestion
                    {
                        QuestionText = q.QuestionText,
                        Type = q.Type,
                        IsRequired = q.IsRequired,
                        Order = q.Order,
                        MinSelectionCount = q.MinSelectionCount,
                        MaxSelectionCount = q.MaxSelectionCount,
                        ExactSelectionCount = q.ExactSelectionCount,
                        Options = q.Options.Select(o => new QuestionOption
                        {
                            OptionText = o.OptionText,
                            Order = o.Order
                        }).ToList()
                    }).ToList()
                };

                survey.Creator = await _userManager.FindByIdAsync(survey.CreatorId);

                _context.Add(survey);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Details), new { id = survey.Id, token = survey.AccessToken });
            }
            return View(viewModel);
        }

        // GET: Surveys/Edit/5
        public async Task<IActionResult> Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var survey = await _context.Surveys
                .Include(s => s.Questions)
                    .ThenInclude(q => q.Options)
                .FirstOrDefaultAsync(s => s.Id == id.Value);

            if (survey == null)
            {
                return NotFound();
            }

            // 检查是否是创建者
            if (survey.CreatorId != User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value)
            {
                return Forbid();
            }

            var viewModel = new SurveyCreateViewModel
            {
                Id = survey.Id,
                Title = survey.Title,
                Description = survey.Description,
                IsPublic = survey.IsPublic,
                IsAnonymous = survey.IsAnonymous,
                Questions = survey.Questions
                    .OrderBy(q => q.Order)
                    .Select(q => new QuestionViewModel
                    {
                        Id = q.Id,
                        QuestionText = q.QuestionText,
                        Type = q.Type,
                        IsRequired = q.IsRequired,
                        Order = q.Order,
                        MinSelectionCount = q.MinSelectionCount,
                        MaxSelectionCount = q.MaxSelectionCount,
                        ExactSelectionCount = q.ExactSelectionCount,
                        Options = q.Options
                            .OrderBy(o => o.Order)
                            .Select(o => new QuestionOptionViewModel
                            {
                                Id = o.Id,
                                OptionText = o.OptionText,
                                Order = o.Order
                            }).ToList()
                    }).ToList()
            };

            return View(viewModel);
        }

        // POST: Surveys/Edit/5
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(int? id, SurveyCreateViewModel viewModel)
        {
            if (id == null || id != viewModel.Id)
            {
                return NotFound();
            }

            var existingSurvey = await _context.Surveys
                .Include(s => s.Questions)
                    .ThenInclude(q => q.Options)
                .FirstOrDefaultAsync(s => s.Id == id.Value);

            if (existingSurvey == null)
            {
                return NotFound();
            }

            // 检查是否是创建者
            if (existingSurvey.CreatorId != User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value)
            {
                return Forbid();
            }

            if (ModelState.IsValid)
            {
                try
                {
                    // 更新问卷基本信息
                    existingSurvey.Title = viewModel.Title;
                    existingSurvey.Description = viewModel.Description;
                    existingSurvey.IsPublic = viewModel.IsPublic;
                    existingSurvey.IsAnonymous = viewModel.IsAnonymous;

                    // 删除现有的问题和选项
                    _context.QuestionOptions.RemoveRange(existingSurvey.Questions.SelectMany(q => q.Options));
                    _context.SurveyQuestions.RemoveRange(existingSurvey.Questions);

                    // 添加新的问题和选项
                    existingSurvey.Questions = viewModel.Questions.Select(q => new SurveyQuestion
                    {
                        QuestionText = q.QuestionText,
                        Type = q.Type,
                        IsRequired = q.IsRequired,
                        Order = q.Order,
                        MinSelectionCount = q.MinSelectionCount,
                        MaxSelectionCount = q.MaxSelectionCount,
                        ExactSelectionCount = q.ExactSelectionCount,
                        Options = q.Options.Select(o => new QuestionOption
                        {
                            OptionText = o.OptionText,
                            Order = o.Order
                        }).ToList()
                    }).ToList();

                    _context.Update(existingSurvey);
                    await _context.SaveChangesAsync();
                    return RedirectToAction(nameof(Details), new { id = existingSurvey.Id, token = existingSurvey.AccessToken });
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!SurveyExists(id.Value))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
            }
            return View(viewModel);
        }

        // GET: Surveys/Delete/5
        public async Task<IActionResult> Delete(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var survey = await _context.Surveys
                .Include(s => s.Creator)
                .FirstOrDefaultAsync(s => s.Id == id);
            if (survey == null)
            {
                return NotFound();
            }

            // 检查是否是创建者
            if (survey.CreatorId != User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value)
            {
                return Forbid();
            }

            return View(survey);
        }

        // POST: Surveys/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> DeleteConfirmed(int id)
        {
            var survey = await _context.Surveys
                .Include(s => s.Questions)
                    .ThenInclude(q => q.Options)
                .Include(s => s.Responses)
                    .ThenInclude(r => r.QuestionResponses)
                        .ThenInclude(qr => qr.SelectedOptions)
                .FirstOrDefaultAsync(s => s.Id == id);

            if (survey == null)
            {
                return NotFound();
            }

            // 检查是否是创建者
            if (survey.CreatorId != User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value)
            {
                return Forbid();
            }

            // 删除所有相关的回答记录
            foreach (var response in survey.Responses)
            {
                foreach (var questionResponse in response.QuestionResponses)
                {
                    _context.OptionResponses.RemoveRange(questionResponse.SelectedOptions);
                }
                _context.QuestionResponses.RemoveRange(response.QuestionResponses);
            }
            _context.SurveyResponses.RemoveRange(survey.Responses);

            // 删除问题和选项
            foreach (var question in survey.Questions)
            {
                _context.QuestionOptions.RemoveRange(question.Options);
            }
            _context.SurveyQuestions.RemoveRange(survey.Questions);

            // 最后删除问卷本身
            _context.Surveys.Remove(survey);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }

        // GET: Surveys/Fill/5
        public async Task<IActionResult> Fill(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var survey = await _context.Surveys
                .Include(s => s.Questions)
                    .ThenInclude(q => q.Options)
                .FirstOrDefaultAsync(s => s.Id == id);

            if (survey == null)
            {
                return NotFound();
            }

            if (!survey.IsActive)
            {
                return View("SurveyEnded", survey);
            }

            if (survey.EndTime.HasValue && survey.EndTime.Value < DateTime.Now)
            {
                return View("SurveyEnded", survey);
            }

            var userId = User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;
            if (userId == null && !survey.IsAnonymous)
            {
                return Forbid();
            }

            // Check if user has already submitted and multiple submissions are not allowed
            if (!survey.AllowMultipleSubmissions && userId != null)
            {
                var existingResponse = await _context.SurveyResponses
                    .AnyAsync(r => r.SurveyId == survey.Id && r.RespondentId == userId);
                
                if (existingResponse)
                {
                    TempData["ErrorMessage"] = "您已经提交过此问卷，每个用户只能提交一次。";
                    return RedirectToAction(nameof(Index));
                }
            }

            var viewModel = new SurveyFillViewModel
            {
                SurveyId = survey.Id,
                Title = survey.Title,
                Description = survey.Description,
                IsAnonymous = survey.IsAnonymous,
                Questions = survey.Questions
                    .OrderBy(q => q.Order)
                    .Select(q => new QuestionFillViewModel
                    {
                        Id = q.Id,
                        QuestionText = q.QuestionText,
                        Type = (int)q.Type,
                        IsRequired = q.IsRequired,
                        Order = q.Order,
                        MinSelectionCount = q.MinSelectionCount,
                        MaxSelectionCount = q.MaxSelectionCount,
                        ExactSelectionCount = q.ExactSelectionCount,
                        Options = q.Options
                            .OrderBy(o => o.Order)
                            .Select(o => new QuestionOptionViewModel
                            {
                                Id = o.Id,
                                OptionText = o.OptionText,
                                Order = o.Order
                            }).ToList()
                    }).ToList()
            };

            return View(viewModel);
        }

        // POST: Surveys/Fill/5
        [HttpPost]
        public async Task<IActionResult> Fill(int id, Dictionary<int, string[]> responses)
        {
            var survey = await _context.Surveys
                .Include(s => s.Questions)
                    .ThenInclude(q => q.Options)
                .FirstOrDefaultAsync(s => s.Id == id);

            if (survey == null)
            {
                TempData["ErrorMessage"] = "问卷不存在";
                return RedirectToAction(nameof(Index));
            }

            if (!survey.IsActive)
            {
                TempData["ErrorMessage"] = "该问卷已结束";
                return RedirectToAction(nameof(Index));
            }

            if (!survey.AllowMultipleSubmissions)
            {
                var userId = User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;
                if (userId != null)
                {
                    var hasSubmitted = await _context.SurveyResponses
                        .AnyAsync(r => r.SurveyId == id && r.RespondentId == userId);
                    if (hasSubmitted)
                    {
                        TempData["ErrorMessage"] = "您已经提交过该问卷";
                        return RedirectToAction(nameof(Index));
                    }
                }
            }

            // 验证必填问题
            var requiredQuestions = survey.Questions.Where(q => q.IsRequired).ToList();
            foreach (var question in requiredQuestions)
            {
                if (!responses.ContainsKey(question.Id))
                {
                    TempData["ErrorMessage"] = $"问题 \"{question.QuestionText}\" 是必填项";
                    return RedirectToAction(nameof(Index));
                }

                var answer = responses[question.Id];
                if (answer == null || answer.Length == 0 || string.IsNullOrWhiteSpace(answer[0]))
                {
                    TempData["ErrorMessage"] = $"问题 \"{question.QuestionText}\" 是必填项";
                    return RedirectToAction(nameof(Index));
                }
            }

            // 创建问卷回答
            var response = new SurveyResponse
            {
                SurveyId = id,
                SubmitTime = DateTime.Now,
                RespondentId = User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value
            };

            _context.SurveyResponses.Add(response);
            await _context.SaveChangesAsync();

            // 处理每个问题的回答
            foreach (var kvp in responses)
            {
                var questionId = kvp.Key;
                var answer = kvp.Value;

                var question = survey.Questions.First(q => q.Id == questionId);
                var questionResponse = new QuestionResponse
                {
                    SurveyResponseId = response.Id,
                    QuestionId = questionId
                };

                switch (question.Type)
                {
                    case QuestionType.SingleChoice: // 单选题
                        if (answer.Length > 0)
                        {
                            questionResponse.SelectedOptions = new List<OptionResponse>
                            {
                                new OptionResponse { OptionId = int.Parse(answer[0]) }
                            };
                        }
                        break;

                    case QuestionType.MultipleChoice: // 多选题
                        if (answer.Length > 0)
                        {
                            // 验证多选题的选择数量
                            if (question.MinSelectionCount.HasValue && answer.Length < question.MinSelectionCount.Value)
                            {
                                TempData["ErrorMessage"] = $"问题 \"{question.QuestionText}\" 至少需要选择 {question.MinSelectionCount.Value} 项";
                                return RedirectToAction(nameof(Index));
                            }
                            if (question.MaxSelectionCount.HasValue && answer.Length > question.MaxSelectionCount.Value)
                            {
                                TempData["ErrorMessage"] = $"问题 \"{question.QuestionText}\" 最多只能选择 {question.MaxSelectionCount.Value} 项";
                                return RedirectToAction(nameof(Index));
                            }
                            if (question.ExactSelectionCount.HasValue && answer.Length != question.ExactSelectionCount.Value)
                            {
                                TempData["ErrorMessage"] = $"问题 \"{question.QuestionText}\" 必须选择 {question.ExactSelectionCount.Value} 项";
                                return RedirectToAction(nameof(Index));
                            }

                            questionResponse.SelectedOptions = answer.Select(optionId => new OptionResponse
                            {
                                OptionId = int.Parse(optionId)
                            }).ToList();
                        }
                        else if (question.IsRequired)
                        {
                            // 如果是必选题，至少需要选择一个选项
                            TempData["ErrorMessage"] = $"问题 \"{question.QuestionText}\" 至少需要选择一个选项";
                            return RedirectToAction(nameof(Index));
                        }
                        break;

                    case QuestionType.Text: // 填空题
                        if (answer.Length > 0)
                        {
                            questionResponse.TextResponse = answer[0];
                        }
                        break;

                    case QuestionType.Rating: // 评分题
                        if (answer.Length > 0)
                        {
                            if (int.TryParse(answer[0], out int rating))
                            {
                                questionResponse.RatingResponse = rating;
                            }
                            else
                            {
                                TempData["ErrorMessage"] = $"问题 \"{question.QuestionText}\" 的评分必须是数字";
                                return RedirectToAction(nameof(Index));
                            }
                        }
                        break;
                }

                _context.QuestionResponses.Add(questionResponse);
            }

            await _context.SaveChangesAsync();
            TempData["SuccessMessage"] = "问卷提交成功！";
            return RedirectToAction(nameof(Details), new { id = survey.Id, source = "fill" });
        }

        // GET: Surveys/FillSuccess/5
        public async Task<IActionResult> FillSuccess(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var survey = await _context.Surveys.FindAsync(id);
            if (survey == null)
            {
                return NotFound();
            }

            return View(survey);
        }

        public async Task<IActionResult> ViewResponse(int responseId)
        {
            var response = await _context.SurveyResponses
                .Include(r => r.QuestionResponses)
                    .ThenInclude(qr => qr.Question)
                .Include(r => r.QuestionResponses)
                    .ThenInclude(qr => qr.SelectedOptions)
                        .ThenInclude(so => so.Option)
                .FirstOrDefaultAsync(r => r.Id == responseId);

            if (response == null)
            {
                return NotFound();
            }

            return View(response);
        }

        [HttpGet]
        public async Task<IActionResult> Export(int id, string format = "pdf")
        {
            var survey = await _context.Surveys
                .Include(s => s.Questions)
                    .ThenInclude(q => q.Options)
                .FirstOrDefaultAsync(s => s.Id == id);

            if (survey == null)
            {
                return NotFound();
            }

            byte[] fileBytes;
            string contentType;
            string fileExtension;

            switch (format.ToLower())
            {
                case "excel":
                    fileBytes = _excelExportService.ExportSurveyToExcel(survey);
                    contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                    fileExtension = "xlsx";
                    break;
                case "pdf":
                default:
                    fileBytes = _pdfExportService.ExportSurveyToPdf(survey);
                    contentType = "application/pdf";
                    fileExtension = "pdf";
                    break;
            }

            return File(fileBytes, contentType, $"{survey.Title}.{fileExtension}");
        }

        private bool SurveyExists(int id)
        {
            return _context.Surveys.Any(e => e.Id == id);
        }
    }
} 